package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.ResourceDto;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.ResourceVo;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

@Service

public class ResourceServiceImpl implements ResourceService {
    @Autowired
    private ResourceMapper resourceMapper;

    /**
     * 资源树形集合
     * @param resourceDto
     * @return
     */
    @Override
    @Cacheable(value = "resource:list",key = "#resourceDto.hashCode()")
    public List<ResourceVo> list(ResourceDto resourceDto) {

        return resourceMapper.list(resourceDto);
    }

    /**
     * 资源树形集合
     *
     * @param resourceDto
     * @return
     */
    @Override
    @Cacheable(value = "resource:tree" ,key = "#resourceDto.hashCode()")
    public TreeVo tree(ResourceDto resourceDto) {
        //对所有的资源集合进行查询   根节点的no为：100001000000000（用常量表示）
        resourceDto.setResourceNo(NoProcessing.processString(SuperConstant.ROOT_PARENT_ID));
        resourceDto.setResourceType(SuperConstant.MENU);
        List<ResourceVo> resourceVos = resourceMapper.list(resourceDto);
        List<TreeItemVo> children = new ArrayList<>();
        ResourceVo resourceVo = new ResourceVo();
        resourceVo.setResourceNo(SuperConstant.ROOT_PARENT_ID);
        resourceVo.setResourceName("智慧养老院");
        buildTree(children,resourceVo,resourceVos);
        TreeVo treeVo = new TreeVo();
        treeVo.setItems(children);
        return treeVo;
    }

    private void buildTree(List<TreeItemVo> children, ResourceVo resourceVo, List<ResourceVo> resourceVos) {
        //类型转换，将ResourceVo转换成
        TreeItemVo treeItemVo = new TreeItemVo();
        treeItemVo.setId(resourceVo.getResourceNo());
        treeItemVo.setLabel(resourceVo.getResourceName());
        List<ResourceVo> vos = resourceVos.stream().filter(item -> item.getParentResourceNo().equals(treeItemVo.getId())).collect(Collectors.toList());
        // 创建空集合，用来装所有的子菜单
        List<TreeItemVo> list = new ArrayList<>();
        if (vos != null && vos.size() > 0 ){
            vos.forEach(item->{
                buildTree(list,item,resourceVos);
            });
            treeItemVo.setChildren(list);
        }
      children.add(treeItemVo);
    }

    /**
     * 新增资源项
     *
     * @param resourceDto
     */
    @Override
    @Caching(evict = {
      @CacheEvict(value = "resource:page",allEntries = true),
      @CacheEvict(value = "resource:list",allEntries = true)
            })
    public void insertResource(ResourceDto resourceDto) {
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
        //父路径的状态是禁用的话子路径初始状态就是就是禁用状态、子随父！！，但是前端已传过来，不必考虑……
        //判断当前的目录是否是三级菜单，如果是三级菜单则抛出异常，不能创建
        String str = NoProcessing.processString(resource.getParentResourceNo());
        if (resourceDto.getResourceType().equals("m") && str.length()>12){
            throw new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);
        }
        //正常的话，正常创建。
        String resourceNo = createResourceNo(resourceDto);
        resource.setResourceNo(resourceNo);
        resourceMapper.insert(resource);

    }

    private String createResourceNo(ResourceDto resourceDto) {
        //根据该父路径查找该路径下的子路径
        List<ResourceVo> list = resourceMapper.list(resourceDto);
        if (list != null && list.size() > 0){
            //子菜单中存在菜单，在原来的基础上加1
            LongStream longStream = list.stream().mapToLong(item -> Long.parseLong(item.getResourceNo()));
            long max = longStream.max().getAsLong();
            String no = NoProcessing.createNo(String.valueOf(max), true);
            return no;
        }
            return NoProcessing.createNo(resourceDto.getParentResourceNo(),false);
    }

    /**
     * 删除资源项
     *
     * @param resourceNo
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "resource:page",allEntries = true),
            @CacheEvict(value = "resource:list",allEntries = true)
    })
    public void delete(String resourceNo) {
        ResourceDto resourceDto = new ResourceDto();
        resourceDto.setParentResourceNo(resourceNo);
        //查询该菜单下面是否还有子菜单，如果有则不能删除
        List<ResourceVo> list = resourceMapper.list(resourceDto);
        if (list != null && list.size() > 0){
            throw new BaseException(BasicEnum.HAS_SON_MENU);
        }
        resourceMapper.delete(resourceNo);
    }

    /**
     * 启用禁用
     *
     * @param resourceDto
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "resource:page",allEntries = true),
            @CacheEvict(value = "resource:list",allEntries = true)
    })
    public void enableState(ResourceDto resourceDto) {

       //0启用···1禁用

        //如果为启用操作的话要查父节点的状态
        if(resourceDto.getDataState().equals("0")){
            //启用操作
            //查询此父节点的状态，如果父节点的状态为禁用状态的话则子节点禁止启用！
          ResourceVo  resourceVo =  resourceMapper.selectByResourceNo(resourceDto.getParentResourceNo());
            if (resourceVo.getDataState().equals("1")){
                throw new BaseException(BasicEnum.PARENT_MENU_DISABLE);
            }

        }
        //到这为禁用操作，禁用本菜单以及本级的所有子菜单
        String str = NoProcessing.processString(resourceDto.getResourceNo());
        resourceMapper.enableState(resourceDto.getDataState(),str);
    }

    /**
     * 修改资源
     *
     * @param resourceDto
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "resource:page",allEntries = true),
            @CacheEvict(value = "resource:list",allEntries = true)
    })
    public void update(ResourceDto resourceDto) {
        //属性拷贝
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
        resourceMapper.update(resource);

    }
}
